/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.geradormvc.persistencia.impl;

import br.com.geradormvc.excessao.GeradorMVCException;
import br.com.geradormvc.modelo.dominio.Principal;
import br.com.geradormvc.modelo.dominio.Tabela;
import br.com.geradormvc.persistencia.IGatewayPrincipal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author douglas
 */
public class GatewayPrincipal implements IGatewayPrincipal {

    private static final String SQL_PESQUISARDATABASE =
            "SELECT datname FROM pg_database WHERE datistemplate IS FALSE";
    private static final String SQL_PESQUISARTABELAS =
            "SELECT tablename FROM pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema')";
    private static final String SQL_PESQUISARCOLUNAS =
            "SELECT tmp.* "
            + "  FROM ("
            + "        SELECT c.relname AS objname,"
            + "               c.relkind AS objkind,"
            + "               a.attnum AS indexnum,"
            + "               a.attname AS fieldname,"
            + "               t.typname AS fieldtype,"
            + "               a.atttypmod-4 as fieldlength,"
            + "               NOT a.attnotnull AS \"isnull\","
            + "               d.adsrc AS defaultvalue"
            + "               FROM pg_attribute AS a"
            + "               JOIN pg_class AS c ON c.oid=a.attrelid AND c.relname !~ '^pg_'"
            + "               JOIN pg_type AS t ON t.oid=a.atttypid"
            + "               LEFT OUTER JOIN pg_attrdef AS d ON c.oid=d.adrelid AND"
            + "               d.adnum=a.attnum"
            + "         WHERE a.attnum > 0"
            + "         ORDER BY c.relkind, c.relname, a.attnum) tmp"
            + " WHERE tmp.objkind = ?"
            + "   AND tmp.objname = ?";

    public List pesquisarDatabase() throws GeradorMVCException {
        Connection con = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        try {
            con = GerenciadorDeConexao.getConexao();
            stmt = con.prepareStatement(SQL_PESQUISARDATABASE);
            rs = stmt.executeQuery();
            List databases = new ArrayList();
            while (rs.next()) {
                //Principal principal = new Principal();
                //principal.setDatabase(rs.getString("datname"));
                databases.add(rs.getString("datname"));
            }

            return databases;
        } catch (SQLException exc) {
            StringBuffer mensagem = new StringBuffer("Não foi possível realizar a consulta.");
            mensagem.append("\nMotivo: " + exc.getMessage());
            throw new GeradorMVCException(mensagem.toString());
        } finally {
            GerenciadorDeConexao.closeConexao(con, stmt, rs);
        }

    }

    public List pesquisarTabelas() throws GeradorMVCException {
        Connection con = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        try {
            con = GerenciadorDeConexao.getConexao();
            stmt = con.prepareStatement(SQL_PESQUISARTABELAS);
            rs = stmt.executeQuery();
            List databases = new ArrayList();
            while (rs.next()) {
                databases.add(rs.getString("tablename"));
            }

            return databases;
        } catch (SQLException exc) {
            StringBuffer mensagem = new StringBuffer("Não foi possível realizar a consulta.");
            mensagem.append("\nMotivo: " + exc.getMessage());
            throw new GeradorMVCException(mensagem.toString());
        } finally {
            GerenciadorDeConexao.closeConexao(con, stmt, rs);
        }

    }

    public List pesquisarColunasTabela(String objName, String objKind) throws GeradorMVCException {

        Connection con = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        try {
            con = GerenciadorDeConexao.getConexao();
            stmt = con.prepareStatement(SQL_PESQUISARCOLUNAS);
            stmt.setString(1, objKind);
            stmt.setString(2, objName);
            rs = stmt.executeQuery();
            List colunasTabelas = new ArrayList();
            while (rs.next()) {
                Tabela tabela = criarColunasTabela(rs);
                colunasTabelas.add(tabela);
            }

            return colunasTabelas;
        } catch (SQLException exc) {
            StringBuffer mensagem = new StringBuffer("Não foi possível realizar a consulta.");
            mensagem.append("\nMotivo: " + exc.getMessage());
            throw new GeradorMVCException(mensagem.toString());
        } finally {
            GerenciadorDeConexao.closeConexao(con, stmt, rs);
        }

    }

    private Tabela criarColunasTabela(ResultSet rs) throws GeradorMVCException {
        Tabela tabela = new Tabela();

        try {
            tabela.setSelecionar(true);
            tabela.setTipoObjeto(rs.getString("objkind"));
            tabela.setNomeColuna(rs.getString("fieldname"));
            tabela.setTipoColuna(rs.getString("fieldtype"));
            tabela.setNulo(rs.getBoolean("isnull"));
        } catch (SQLException exc) {
            StringBuffer mensagem = new StringBuffer("Não foi possível obter os dados do sócio.");
            mensagem.append("\nMotivo: " + exc.getMessage());
            throw new GeradorMVCException(mensagem.toString());
        }

        return tabela;
    }
}
